package com.utils.io;

import lombok.Cleanup;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.slf4j.MDC;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;

/**
 * 文件流扩展，读取文件流时基于内容生成 MD5 值
 * 参考： com.amazonaws.services.s3.internal.MD5DigestCalculatingInputStream
 *
 * @author 谢长春 2020-11-24
 * @deprecated 废弃类： 使用 org.apache.commons.codec.digest.DigestUtils.md5Hex(inputStream) 替代
 */
@Deprecated
@Slf4j
public class Md5BufferedInputStream extends BufferedInputStream {
    //    private final MessageDigest messageDigest;
    private final String md5Hex;

    @SneakyThrows
    public Md5BufferedInputStream(final InputStream inputStream) {
        super(inputStream);
//        messageDigest = MessageDigest.getInstance("MD5");
        this.md5Hex = DigestUtils.md5Hex(inputStream);
    }

    @SneakyThrows
    public Md5BufferedInputStream(final InputStream inputStream, final int size) {
        super(inputStream, size);
//        messageDigest = MessageDigest.getInstance("MD5");
        this.md5Hex = DigestUtils.md5Hex(inputStream);
    }

//    @SneakyThrows
//    @Override
//    public int read(final byte[] bytes) {
//        final int count = super.read(bytes, 0, bytes.length);
//        if (count != -1) {
//            messageDigest.update(bytes, 0, count);
//        }
//        return count;
//    }
//
//    @SneakyThrows
//    @Override
//    public synchronized int read() {
//        final int count = super.read();
//        if (count != -1) {
//            messageDigest.update((byte) count);
//        }
//        return count;
//    }
//
//    @SneakyThrows
//    @Override
//    public synchronized int read(byte[] bytes, int off, int len) {
//        final int count = super.read(bytes, off, len);
//        if (count != -1) {
//            messageDigest.update(bytes, 0, count);
//        }
//        return count;
//    }

    @SneakyThrows
    public String getMd5() {
//            log.info("available() s:{}", available());
//            final int len = available();
//            final int length = 4096;
//            final byte[] bytes = new byte[length];
//            int count;
//            while ((count = read(bytes, 0, length)) != -1) {
//                messageDigest.update(bytes, 0, count);
//            }
//            log.info("available() e:{}", available());
//            skip(-len);
//            log.info("available() e:{}", available());
//            this.md5Hex = Hex.encodeHexString(messageDigest.digest());
        return md5Hex;
    }

    @SneakyThrows
    public static void main(final String[] args) {
        Files.list(Paths.get("/home/ccx/git-repository/common-mvc-parent/logs/")).forEach(path -> {
            try {
                File file = path.toFile();
                MDC.put("traceId", file.getName());
                {
                    @Cleanup final FileInputStream inputStream = new FileInputStream(file);
                    @Cleanup final Md5BufferedInputStream md5BufferedInputStream = new Md5BufferedInputStream(inputStream);
                    final byte[] bytes = new byte[2048];
                    int count;
                    while ((count = md5BufferedInputStream.read(bytes)) != -1) {
                    }
                    log.info("{}:{}:{}",
                            DigestUtils.md5Hex(new FileInputStream(file)),
                            md5BufferedInputStream.getMd5(),
                            file.getAbsolutePath()
                    );
                }
            } catch (IOException e) {
                log.error(e.getMessage(), e);
            }
        });

    }
}

